React Suspense Ressourcen-Deduplizierung: Doppelte Anfragen verhindern | MLOG | MLOG

Jetzt prüft die UserResource, ob eine Ressource bereits im cache vorhanden ist. Wenn ja, wird die gecachte Ressource zurückgegeben. Andernfalls wird eine neue Anfrage initiiert und das resultierende Promise im Cache gespeichert. Dies stellt sicher, dass für jede eindeutige userId nur eine Anfrage gestellt wird.

2. Verwendung einer dedizierten Caching-Bibliothek (z. B. `lru-cache`)

Für komplexere Caching-Szenarien sollten Sie die Verwendung einer dedizierten Caching-Bibliothek wie lru-cache oder ähnlichem in Betracht ziehen. Diese Bibliotheken bieten Funktionen wie Cache-Eviction basierend auf Least Recently Used (LRU) oder anderen Richtlinien, was für die Verwaltung der Speichernutzung, insbesondere bei einer großen Anzahl von Ressourcen, entscheidend sein kann.

Installieren Sie zuerst die Bibliothek:

            
npm install lru-cache

            

Integrieren Sie sie dann in Ihre UserResource:

            
import React, { Suspense } from 'react';
import LRUCache from 'lru-cache';

const fetchUser = (userId) => {
  console.log(`Fetching user with ID: ${userId}`); // Netzwerkanfrage simulieren
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ id: userId, name: `User ${userId}`, email: `user${userId}@example.com` });
    }, 1000); // Netzwerklatenz simulieren
  });
};

const cache = new LRUCache({
  max: 100, // Maximale Anzahl von Elementen im Cache
  ttl: 60000, // Time-to-live in Millisekunden (1 Minute)
});

const UserResource = (userId) => {
  if (!cache.has(userId)) {
    let promise = null;
    let status = 'pending'; // ausstehend, erfolgreich, fehlerhaft
    let result;

    const suspender = fetchUser(userId).then(
      (r) => {
        status = 'success';
        result = r;
        cache.set(userId, {
          read() {
            return result;
          },
        });
      },
      (e) => {
        status = 'error';
        result = e;
        cache.set(userId, {
          read() {
            throw result;
          },
        });
      }
    );

    cache.set(userId, {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        }
    });
  }

  return cache.get(userId);
};


const UserProfile = ({ userId }) => {
  const user = UserResource(userId).read();
  return (
    

User Profile

ID: {user.id}

Name: {user.name}

Email: {user.email}

); }; const UserDetails = ({ userId }) => { const user = UserResource(userId).read(); return (

User Details

ID: {user.id}

Name: {user.name}

); }; const App = () => { return ( Loading...
}> ); }; export default App;

Dieser Ansatz bietet mehr Kontrolle über die Größe und die Ablaufrichtlinie des Caches.

3. Request Coalescing mit Bibliotheken wie `axios-extensions`

Bibliotheken wie axios-extensions bieten erweiterte Funktionen wie Request Coalescing. Request Coalescing fasst mehrere identische Anfragen zu einer einzigen Anfrage zusammen und optimiert so die Netzwerknutzung weiter. Dies ist besonders nützlich in Szenarien, in denen Anfragen zeitlich sehr nahe beieinander initiiert werden.

Installieren Sie zuerst die Bibliothek:

            
npm install axios axios-extensions

            

Konfigurieren Sie dann Axios mit dem von axios-extensions bereitgestellten cache-Adapter.

Beispiel für die Verwendung von `axios-extensions` und die Erstellung einer Ressource:

            
import React, { Suspense } from 'react';
import axios from 'axios';
import { cacheAdapterEnhancer, throttleAdapterEnhancer } from 'axios-extensions';

const instance = axios.create({
  baseURL: 'https://api.example.com', // Ersetzen Sie dies durch Ihren API-Endpunkt
  adapter: cacheAdapterEnhancer(axios.defaults.adapter, { enabledByDefault: true }),
});

const fetchUser = async (userId) => {
  console.log(`Fetching user with ID: ${userId}`); // Netzwerkanfrage simulieren
  const response = await instance.get(`/users/${userId}`);
  return response.data;
};


const UserResource = (userId) => {
    let promise = null;
    let status = 'pending'; // ausstehend, erfolgreich, fehlerhaft
    let result;

    const suspender = fetchUser(userId).then(
        (r) => {
            status = 'success';
            result = r;
        },
        (e) => {
            status = 'error';
            result = e;
        }
    );

    return {
        read() {
            if (status === 'pending') {
                throw suspender;
            } else if (status === 'error') {
                throw result;
            }
            return result;
        },
    };
};


const UserProfile = ({ userId }) => {
  const user = UserResource(userId).read();
  return (
    

User Profile

ID: {user.id}

Name: {user.name}

Email: {user.email}

); }; const UserDetails = ({ userId }) => { const user = UserResource(userId).read(); return (

User Details

ID: {user.id}

Name: {user.name}

); }; const App = () => { return ( Loading...
}> ); }; export default App;

Dies konfiguriert Axios zur Verwendung eines Cache-Adapters, der Antworten automatisch basierend auf der Anfragekonfiguration zwischenspeichert. Die cacheAdapterEnhancer-Funktion bietet Optionen zur Konfiguration des Caches, wie z. B. das Festlegen einer maximalen Cache-Größe oder einer Ablaufzeit. throttleAdapterEnhancer kann ebenfalls verwendet werden, um die Anzahl der an den Server gestellten Anfragen innerhalb eines bestimmten Zeitraums zu begrenzen und die Leistung weiter zu optimieren.

Best Practices für die Ressourcenduplizierung

Globale Überlegungen zum Datenabruf und zur Deduplizierung

Bei der Gestaltung von Datenabrufstrategien für ein globales Publikum spielen mehrere Faktoren eine Rolle:

Beispielsweise könnte eine Reisebuchungswebsite, die sich an ein globales Publikum richtet, ein CDN verwenden, um Flug- und Hotelverfügbarkeitsdaten von Servern in verschiedenen Regionen bereitzustellen. Die Website würde auch eine Währungsumrechnungs-API verwenden, um Preise in der lokalen Währung des Benutzers anzuzeigen und Optionen zum Filtern von Suchergebnissen basierend auf Spracheinstellungen bereitzustellen.

Fazit

Die Ressourcenduplizierung ist eine wesentliche Optimierungstechnik für React-Anwendungen, die Suspense verwenden. Indem Sie doppelte Datenabrufanfragen verhindern, können Sie die Leistung erheblich verbessern, die Serverlast reduzieren und die Benutzererfahrung verbessern. Ob Sie sich für die Implementierung eines einfachen Promise-Caches entscheiden oder fortschrittlichere Bibliotheken wie lru-cache oder axios-extensions nutzen, der Schlüssel liegt darin, die zugrunde liegenden Prinzipien zu verstehen und die Lösung zu wählen, die am besten zu Ihren spezifischen Anforderungen passt. Denken Sie daran, globale Faktoren wie CDNs, Lokalisierung und Barrierefreiheit bei der Gestaltung Ihrer Datenabrufstrategien für ein vielfältiges Publikum zu berücksichtigen. Durch die Umsetzung dieser Best Practices können Sie schnellere, effizientere und benutzerfreundlichere React-Anwendungen erstellen.